from flask import request, jsonify
from flaskapp.entity.Rent import Rent
from flaskapp.entity.House import House
from flaskapp.entity.User import User
from flaskapp.util.Redprint import Redprint
from flaskapp.util.Result import Result
from flaskapp.util.jwt_optional_for_options import jwt_optional_for_options
from flaskapp.util.Sqlalchemy import db
from datetime import datetime
from sqlalchemy import func, extract
from flaskapp.entity.Maintain import Maintain
from flask_jwt_extended import get_jwt_identity

api = Redprint('rent')

@api.route('/apply', methods=['POST', 'OPTIONS'])
@jwt_optional_for_options
def apply_rent():
    """提交租房申请"""
    try:
        if request.method == 'OPTIONS':
            return '', 204

        # 获取当前用户信息
        payload = request.jwt_payload
        tenant_id = payload.get('user_id')
        
        # 获取请求数据
        data = request.json
        house_id = data.get('house_id')
        landlord_id = data.get('landlord_id')
        start_date = datetime.strptime(data.get('start_date'), '%Y-%m-%d').date()
        end_date = datetime.strptime(data.get('end_date'), '%Y-%m-%d').date()
        amount = data.get('amount')
        pay_type = data.get('pay_type', '支付宝')

        # 验证必要字段
        if not all([house_id, landlord_id, start_date, end_date, amount]):
            return Result.error(400, '缺少必要参数')

        # 创建租房记录
        new_rent = Rent(
            tenant_id=tenant_id,
            landlord_id=landlord_id,
            house_id=house_id,
            start_date=start_date,
            end_date=end_date,
            amount=amount,
            rent_date=datetime.now().date(),
            pay_type=pay_type
        )

        # 保存到数据库
        db.session.add(new_rent)
        db.session.commit()

        # 更新房屋状态为“出租中”
        house = db.session.query(House).filter_by(house_id=house_id).first()
        if house:
            house.status = '出租中'
            db.session.commit()

         # 查询关联信息
        house = db.session.query(House).filter_by(house_id=house_id).first()
        tenant = db.session.query(User).filter_by(user_id=tenant_id).first()
        landlord = db.session.query(User).filter_by(user_id=landlord_id).first()
        rent = db.session.query(Rent).filter_by(house_id=house_id).first()

        # 构建返回数据
        result_data = new_rent.to_dict()
        result_data.update({
            'house_name': house.description if house else None,
            'tenant_name': tenant.account_name if tenant else None,
            'landlord_name': landlord.account_name if landlord else None,
            'rent_id': rent.rent_id if rent else None,
            'rent_date': rent.rent_date.isoformat() if rent else None,
        })

        return Result.success(result_data, '租房申请提交成功')
    except Exception as e:
        db.session.rollback()
        return Result.error(500, f'服务器错误: {str(e)}')

@api.route('/statistics', methods=['GET', 'OPTIONS'])
@jwt_optional_for_options
def get_rent_statistics():
    """获取租赁数据统计信息"""
    try:
        if request.method == 'OPTIONS':
            return '', 204
            
        # 获取当前用户信息
        payload = request.jwt_payload
        user_id = payload.get('user_id')
        is_admin = payload.get('is_admin', False)
        
        # 构建查询 - 按年月分组统计租赁数量和金额
        # 提取年份和月份
        year = extract('year', Rent.rent_date)
        month = extract('month', Rent.rent_date)
        
        # 如果是管理员，查询所有数据；否则只查询与当前用户相关的数据
        query = db.session.query(
            year.label('year'),
            month.label('month'),
            func.count(Rent.rent_id).label('count'),
            func.sum(Rent.amount).label('total_amount')
        ).group_by(year, month).order_by(year, month)
        
        if not is_admin:
            # 非管理员只能查看自己作为房东的租赁数据
            query = query.filter(Rent.landlord_id == user_id)
        
        # 执行查询
        results = query.all()
        
        # 格式化结果
        statistics = []
        for row in results:
            statistics.append({
                'year': int(row.year),
                'month': int(row.month),
                'count': row.count,
                'total_amount': float(row.total_amount) if row.total_amount else 0
            })
        
        return Result.success(statistics, '获取租赁统计数据成功')
    except Exception as e:
        return Result.error(500, f'服务器错误: {str(e)}')

@api.route('/rentList', methods=['GET', 'OPTIONS'])
# @jwt_required()
@jwt_optional_for_options
def get_rent_list():
    """获取租赁详细信息列表"""
    try:
        if request.method == 'OPTIONS':
            return '', 204
            
        # 获取当前用户信息
        payload = request.jwt_payload
        user_id = payload.get('user_id')
        is_admin = payload.get('is_admin', False)
        
        # 获取时间筛选参数
        startDate = request.args.get('startDate')
        endDate = request.args.get('endDate')
        
        # 创建房东用户的别名
        LandlordUser = db.aliased(User, name='landlord')
        
        # 构建关联查询
        query = db.session.query(
            Rent,
            House.description.label('house_name'),
            User.account_name.label('tenant_name'),
            LandlordUser.account_name.label('landlord_name'),
            House.photo_url.label('photo_url')
        ).join(
            House, Rent.house_id == House.house_id
        ).join(
            User, Rent.tenant_id == User.user_id
        ).join(
            LandlordUser, Rent.landlord_id == LandlordUser.user_id
        )
        
        # 如果不是管理员，只显示与当前用户相关的租赁记录
        if not is_admin:
            query = query.filter((Rent.tenant_id == user_id))
        
        # 添加时间筛选条件
        if startDate:
            try:
                start_date = datetime.strptime(startDate, '%Y-%m-%d').date()
                query = query.filter(Rent.rent_date >= start_date)
            except ValueError:
                return Result.error(400, '起始日期格式错误，请使用YYYY-MM-DD格式')
                
        if endDate:
            try:
                end_date = datetime.strptime(endDate, '%Y-%m-%d').date()
                query = query.filter(Rent.rent_date <= end_date)
            except ValueError:
                return Result.error(400, '终止日期格式错误，请使用YYYY-MM-DD格式')
        
        # 执行查询
        results = query.all()
        
        # 格式化结果
        rent_list = []
        for row in results:
            rent = row[0]
            rent_list.append({
                'rent_id': rent.rent_id,
                'house_name': row[1],  # House.description
                'tenant_name': row[2],  # User.account_name (tenant)
                'landlord_name': row[3],  # User.account_name (landlord)
                'photo_url': row[4],  # House.photo_url
                'amount': float(rent.amount),
                'rent_date': rent.rent_date.isoformat() if rent.rent_date else None,
                'pay_type': rent.pay_type,
                'start_date': rent.start_date.isoformat() if rent.start_date else None,
                'end_date': rent.end_date.isoformat() if rent.end_date else None,
                'landlord_id': rent.landlord_id,
                'house_id': rent.house_id,
            })
        
        return Result.success(rent_list, '获取租赁详细信息列表成功')
    except Exception as e:
        return Result.error(500, f'服务器错误: {str(e)}')


@api.route('/request', methods=['POST'])
@jwt_optional_for_options
def submit_maintenance_request():
    """提交维修请求"""
    try:
        if request.method == 'OPTIONS':
            return '', 204

        # 获取当前用户信息
        payload = request.jwt_payload
        if not payload:
            return Result.error(401, '用户未登录')
        tenant_id = payload.get('user_id')

        # 获取请求体数据
        data = request.get_json()
        landlord_id = data.get('landlord_id')
        house_id = data.get('house_id')
        description = data.get('description')

        # 参数校验
        if not all([tenant_id, landlord_id, house_id, description]):
            return Result.error(400, '缺少必要参数')

        # 创建维修请求对象
        new_request = Maintain(
            tenant_id=tenant_id,
            landlord_id=landlord_id,
            house_id=house_id,
            content=description  # 映射到数据库字段
        )

        db.session.add(new_request)
        db.session.commit()

        return Result.success(new_request.to_dict(), '维修请求提交成功')
    except Exception as e:
        db.session.rollback()
        return Result.error(500, f'服务器错误: {str(e)}')
    
    
@api.route('/maintenanceStatus', methods=['GET'])
@jwt_optional_for_options
def get_maintenance_status():
    """获取当前用户的维修申请状态列表"""
    user_id = request.jwt_payload.get('user_id')

    query = db.session.query(
        Maintain,
        House.description.label('house_name')
    ).join(
        House, Maintain.house_id == House.house_id
    ).filter(
        Maintain.tenant_id == user_id
    ).order_by(
        Maintain.submitted_at.desc()
    )

    results = query.all()
    data = []
    for req, house_name in results:
        data.append({
            'house_name': house_name,
            'content': req.content,
            'submitted_at': req.submitted_at.strftime('%Y-%m-%d %H:%M:%S') if req.submitted_at else '',
            'status': req.status,
            'processed_at': req.processed_at.strftime('%Y-%m-%d %H:%M:%S') if req.processed_at else '',
            'result_notes': req.result_notes or ''
        })

    return Result.success(data)